/******************************************************************************************************************/
/*****************************Description du programme*************************************************************/
//  Auteur: CHOKKI Abiola Paterne & Thanh
//
//  Description: ce programme permet de faire la reconnaissance de chiffres
/******************************************************************************************************************/
/******************************************************************************************************************/
#include "main.h"

int mainsv(int argc, char* argv[]) {
	// les parametres
	bool isLearning = true;
	int dataCode = 2;// 1: training data, 2: test data, 3: validation data
	int rows = 14, cols = 14;
	int knn = 3;
    for( int i = 1; i < argc; i++ )
    {
		const char* s = argv[i];
		if (strcmp(s, "-learn") == 0) {
			isLearning = true;
		} else if (strcmp(s, "-recog") == 0) {
			isLearning = false;
			dataCode = atoi(argv[++i]);
		} else if (strcmp(s, "-r") == 0) {
			rows = atoi(argv[++i]);
		} else if (strcmp(s, "-c") == 0) {
			cols = atoi(argv[++i]);
		} else if (strcmp(s, "-k") == 0) {
			knn = atoi(argv[++i]);
		} else {
			std::cout << "not recognize command" << std::endl;
			return -1;
		}
    }

	//
	vector<vector<vector<double>>> listNumberDescriptors;
	if (isLearning) {
		// PHRASE D'APPRENTISSAGE
		listNumberDescriptors = Data::learning(rows ,cols);

		std::cout << listNumberDescriptors.size() << std::endl;
		std::cout << listNumberDescriptors[0][0].size() << std::endl;
		for (int number = 0; number < 10; number++) {
			std::cout << "number: " << number << " number descriptors: "
					  << listNumberDescriptors[number].size() << std::endl;
		}

		Data::enregisterDescriptor(listNumberDescriptors, "learn.txt");

	} else {
		// PHRASE DE RECONNAISSANCE
		listNumberDescriptors = Data::recupDescriptor("learn.txt");
		// for calculate time of recognition
		time_t timer1, timer2;
		double seconds;
		time(&timer1);  // get current time; same as: timer = time(NULL)
		//-----------------------------------------------------------------
		//--------------------------RECOGNITION----------------------------
		//-----------------------------------------------------------------
		//test
		int good = 0, bad = 0;
		//	int clIdx = -1;
		// read training data
		vector<classImage> listTestingImage = Data::getData(dataCode);

		for (uint i = 0; i < listTestingImage.size(); i++) {
			listTestingImage[i].signature = Utils::getDescriptors(
					listTestingImage[i].image, rows, cols);
		}

		for (uint i = 0; i < listTestingImage.size(); i++) {
			listTestingImage[i].chiffreTrouve = Data::recognizeNearest(
					listTestingImage[i].signature, listNumberDescriptors, 1.15);
			if (listTestingImage[i].chiffreTrouve
					== listTestingImage[i].chiffreReel) {
				good++;
			} else {
				bad++;
			}
		}
		//-----------------------------------------------------------------
		time(&timer2);  // get current time; same as: timer = time(NULL)
		seconds = difftime(timer2, timer1);
		std::cout << "time of recognition: " << seconds << "s" << std::endl;

		std::cout << "good: " << good << " bad: " << bad << std::endl;
		std::cout << "taux: " << good * 1.0 / (good + bad) << std::endl;
	}
	return 0;
}

int main(int argc, char* argv[]) {
	int rowsCut = atoi(argv[1]);
	int colsCut = atoi(argv[2]);
	int dataCode = atoi(argv[3]);
	int knn = atoi(argv[4]);
	cv::vector<classImage> datatraining = Data::getData(1);
	for (uint i = 0; i < datatraining.size(); i++){
		datatraining[i].signature = Utils::getDescriptors(datatraining[i].image, rowsCut, colsCut);
	}
	cv::vector<classImage> datatest = Data::getData(dataCode);
	for (uint i = 0; i < datatest.size(); i++){
		datatest[i].signature = Utils::getDescriptors(datatest[i].image, rowsCut, colsCut);
	}

	cv::Mat trainingData = Learning::convertToMatData(datatraining);
	cv::Mat trainingClasses  = Learning::convertToMatClasse(datatraining);
	cv::Mat testData = Learning::convertToMatData(datatest);
	cv::Mat testClasses = Learning::convertToMatClasse(datatest);

	std::cout << datatraining.size()<< std::endl;
	std::cout << datatest.size()<< std::endl;
	std::cout << trainingData.size()<< std::endl;
	std::cout << trainingClasses.size()<< std::endl;
	std::cout << testData.size()<< std::endl;
	std::cout << testClasses.size()<< std::endl;

	cv::Mat predicted;

//	// SVM
//	predicted = Learning::svm(trainingData, trainingClasses, testData,
//			testClasses);
//	Learning::evaluate(predicted, testClasses);
//	// Knn
//	predicted = Learning::knn(trainingData, trainingClasses, testData,
//			testClasses, knn);
//	Learning::evaluate(predicted, testClasses);
//	// MLP
	std::cout << "MLP" << std::endl;
	predicted = Learning::mlp(trainingData, trainingClasses, testData,
			testClasses);
	Learning::evaluate(predicted, testClasses);
	// bayes
//	predicted = Learning::bayes(trainingData, trainingClasses, testData,
//			testClasses);
//	Learning::evaluate(predicted, testClasses);
	// decisiontree
//	predicted = Learning::decisiontree(trainingData, trainingClasses, testData,
//			testClasses);
//	Learning::evaluate(predicted, testClasses);

	return 0;
}
